﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using EventPlanner.Models;
using System.Web.Security;
using System.Net.Mail;
using System.Net;
using EventPlanner.Servicios;

namespace EventPlanner.Controllers
{ 
    public class UsuarioController : Controller
    {
        IDbContext db;

        /*Constructor sin parámetros: crea una instancia de la clase a partir de la base de datos real de EventPlanner */
        public UsuarioController()
        {
            db = new EventPlannerDB();            
        }

        /*Constructor con un parámetro: crea una instancia de la clase a partir de una base de datos simulada como parámetro */         
        public UsuarioController(IDbContext fake_db)
        {
            db = fake_db;
        }


        /*GET - Muestra los datos del usuario actualmete logueado */
        public ActionResult Index()
        {            
            Usuario usuario = UsuarioActual();
            if (usuario == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El usuario no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 1 }));
            }
            return View(usuario);
        }

        /* Muestra los participantes de un evento obtenido como parámetro */
        public ActionResult VerParticipantes(int id)
        {            
            ViewBag.EventoId = id;
            var evento = db.Find<Evento>(id);
            if (evento == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El evento no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 3 }));
            }            
            return View(evento.UsuariosInscriptos);
        }

        /* Muestra la pantalla de envio de mails de los participantes inscriptos en un evento obtenido como parámetro */
        public ActionResult EnviarMails(int id)
        {
            var evento = db.Find<Evento>(id);
            if (evento == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El evento no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 3 }));
            }            
            return View(evento.UsuariosInscriptos);
        }

        /* Envia los mails a los participantes inscriptos en un evento obtenido como parámetro 
         recibe 3 parametros mas de la vista:
         - selcontactos: Contiene la lista de mails de los contactos seleccionados.
         - subject: Contiene el asunto del mensaje.
         - body: Contiene el cuerpo del mensaje.
         */
        [HttpPost]
        [Authorize]
        public ActionResult EnviarMails(int id, string[] selcontactos, string subject, string body)
        {
            var misusuarios = db.Find<Evento>(id).UsuariosInscriptos;

            if (selcontactos == null)
            {                
                return View(misusuarios);
            }
            else
            {                
                Correo MiCorreo = new Correo();
                try
                {
                    MiCorreo.EnviarMail(selcontactos, subject, body);                    
                    TempData["notice"] = "Mails enviados satisfactoriamente";
                    return View(misusuarios);
                }
                catch (Exception ex)
                {
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                    TempData["notice"] = ex.Message;
                    return View(misusuarios);
                }


            }

            

        }

        //
        // GET: /Usuario/Details/5

        public ActionResult Details(int id)
        {            
            Usuario usuario = db.Find<Usuario>(id);
            if (usuario == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El usuario no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 4 }));
            }            
            return View(usuario);
        }


        /*GET - Muestra la vista de creacion de usuarios */
        public ActionResult Create()
        {
            return View();
        } 

        
        /*POST - Crea un nuevo usuario: recibe como parámetro el usuario creado en la vista y lo agrega a la base de datos  */
        [HttpPost]
        public ActionResult Create(Usuario NuevoUsuario)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    NuevoUsuario.WebSiteUser = db.GetActualUser();
                    db.Add<Usuario>(NuevoUsuario);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch (System.Exception e)
                {
                    Elmah.ErrorSignal.FromCurrentContext().Raise(e);
                    return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 5 }));                
                }
            }
            return View(NuevoUsuario);
        }
        
        

        /*GET - Muestra la vista de edicion de un usuario a partir de su id recibido como parametro   */
        public ActionResult Edit(int id)
        {            
            Usuario usuario = db.Find<Usuario>(id);
            if (usuario == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El usuario no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 1 }));
            }
            return View(usuario);            
        }

        
        /*POST - Agrega el usuario enviado por la vista a la base de datos  */
        [HttpPost]
        public ActionResult Edit(Usuario usuario)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    usuario.WebSiteUser = db.GetActualUser();
                    db.Attach<Usuario>(usuario);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch (System.Exception e)
                {
                    Elmah.ErrorSignal.FromCurrentContext().Raise(e);
                    return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 5 }));                
                }
            }
            return View(usuario);
        }


        /*GET - Muestra la vista de eliminacion de un usuario a partir de su id recibido como parámetro   */
        public ActionResult Delete(int id)
        {
            Usuario usuario = db.Find<Usuario>(id);
            if (usuario == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El usuario no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 1 }));
            }

            if (usuario.EventosCreados.Count > 0)
                ViewBag.Eventos = usuario.EventosCreados.Count;
            if (usuario.Contactos.Count > 0)
                ViewBag.Contactos = usuario.Contactos.Count;

            return View(usuario);
        }


        /*POST - Elimina un usuario y todos sus eventos y contactos que caso de existir   */
        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            Usuario usuario = db.Find<Usuario>(id);
            if (usuario == null)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new System.NullReferenceException("El usuario no puede ser nulo"));
                return (RedirectToAction("ErrorAmigable", "Excepcion", new { NumError = 1 }));
            }

            int CantidadDeEventos = usuario.EventosCreados.Count;
            int CantidadDeContactos = usuario.Contactos.Count;

            for (int i = 1; i <= CantidadDeEventos; i++)
            {
                db.Delete<Evento>(usuario.EventosCreados.First());
                //db.Eventos.Remove(usuario.EventosCreados.First());
                db.SaveChanges();
            }
            for (int i = 1; i <= CantidadDeContactos; i++)
            {
                db.Delete<Contacto>(usuario.Contactos.First());                
                db.SaveChanges();
            }
            
            bool quepaso = Membership.DeleteUser(db.GetActualUser(), true);
            db.Delete<Usuario>(usuario);            
            db.SaveChanges();
            return RedirectToAction("LogOff", "Account");            
        }


        /* Devuelve el usuario actualmete logueado */
        private Usuario UsuarioActual()
        {
            string user = db.GetActualUser();
            var Usuarios = from u in db.Usuarios
                           where u.WebSiteUser == user
                           select u;
            Usuario usuario;
            try
            {
                usuario = Usuarios.First();
                return (usuario);
            }
            catch (System.InvalidOperationException)
            {
                return (null);
            }
        }

        
    }
}